/* Copyright 2012 SionEngine
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siondream.core.animation;
import com.badlogic.gdx.assets.AssetDescriptor;
import com.badlogic.gdx.assets.AssetLoaderParameters;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.assets.loaders.AsynchronousAssetLoader;
import com.badlogic.gdx.assets.loaders.FileHandleResolver;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Animation.PlayMode;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.JsonReader;
import com.badlogic.gdx.utils.JsonValue;
import com.badlogic.gdx.utils.JsonValue.JsonIterator;
import com.badlogic.gdx.utils.Logger;
import com.siondream.core.Env;
/**
* @class AnimationLoader
* @author David Saltares Márquez
* @date 09/09/2012
*
* @brief Asynchronous asset loader for AnimationData objects
*
*/
public class SpriteAnimationLoader extends AsynchronousAssetLoader<SpriteAnimationData, SpriteAnimationLoader.AnimationParameter > {
static public class AnimationParameter extends AssetLoaderParameters<SpriteAnimationData> {
}
private SpriteAnimationData animationData = null;
private Logger logger;
/**
* Creates a new AnimationLoader
*
* @param resolver file resolver to be used
*/
public SpriteAnimationLoader(FileHandleResolver resolver) {
super(resolver);
animationData = null;
logger = new Logger("Animation", Env.debugLevel);
}
/**
* Aynchronously loads the animation data animations
*/
@Override
public void loadAsync(AssetManager manager, String fileName, FileHandle file, AnimationParameter parameter) {
logger.info("loading " + fileName);
animationData = new SpriteAnimationData();
// Retrieve texture
animationData.texture = manager.get(stripExtension(fileName) + ".png", Texture.class);
try {
JsonReader reader = new JsonReader();
JsonValue root = reader.parse(file);
animationData.rows = root.getInt("rows");
animationData.columns = root.getInt("columns");
animationData.frameDuration = root.getFloat("frameDuration");
JsonValue animations = root.get("animations");
JsonIterator animationsIt = animations.iterator();
boolean first = true;
while (animationsIt.hasNext()) {
JsonValue animationValue = animationsIt.next();
String name = animationValue.getString("name");
String frames = animationValue.getString("frames");
Animation animation = new Animation(animationData.frameDuration,
getAnimationFrames(animationData.texture, frames),
getPlayMode(animationValue.getString("mode", "normal")));
animationData.animations.put(name, animation);
logger.info("" + fileName + " loaded animation " + name);
if (first) {
animationData.defaultAnimation = animation;
first = false;
}
}
} catch (Exception e) {
logger.error("error loading file " + fileName + " " + e.getMessage());
}
}
/**
* Retrieves the animation data as it is (without loading anything, this is strictly asynchronous)
*/
@Override
public SpriteAnimationData loadSync(AssetManager manager, String fileName, FileHandle file, AnimationParameter parameter) {
return animationData;
}
/**
* Gets animation data dependencies, this is, the spreadsheet texture to load
*/
@Override
public Array<AssetDescriptor> getDependencies(String fileName, FileHandle file, AnimationParameter parameter) {
Array<AssetDescriptor> dependencies = new Array<AssetDescriptor>();
dependencies.add(new AssetDescriptor<Texture>(stripExtension(fileName) + ".png", Texture.class));
return dependencies;
}
private String stripExtension (String fileName) {
if (fileName == null) return null;
int pos = fileName.lastIndexOf(".");
if (pos == -1) return fileName;
return fileName.substring(0, pos);
}
private PlayMode getPlayMode(String mode) {
if (mode.equals("normal")) {
return PlayMode.NORMAL;
}
else if (mode.equals("loop")) {
return PlayMode.LOOP;
}
else if (mode.equals("loop_pingpong")) {
return PlayMode.LOOP_PINGPONG;
}
else if (mode.equals("loop_random")) {
return PlayMode.LOOP_RANDOM;
}
else if (mode.equals("loop_reversed")) {
return PlayMode.LOOP_REVERSED;
}
else if (mode.equals("reversed")) {
return PlayMode.REVERSED;
}
else {
return PlayMode.NORMAL;
}
}
private Array<TextureRegion> getAnimationFrames(Texture texture, String frames) {
Array<TextureRegion> regions = new Array<TextureRegion>();
if (frames != null) {
String[] framesArray = frames.replaceAll(" ", "").split(",");
int numFrames = framesArray.length;
int width = texture.getWidth() / animationData.columns;
int height = texture.getHeight() / animationData.rows;
for (int i = 0; i < numFrames; ++i) {
int frame = Integer.parseInt(framesArray[i]);
int x = (frame % animationData.columns) * width;
int y = (frame / animationData.columns) * height;
regions.add(new TextureRegion(texture, x, y, width, height));
}
}
return regions;
}
}